var utils = require('common/utils');

module.exports = new EventEmitter();

function EventEmitter() {
  this._cache = {};
}

EventEmitter.prototype.on = function (type, callback) {
  if (!type || !callback) {
    throw new Error('参数 type, callback 是必传参数');
  }
  if (!utils.isString(type)) {
    throw new Error('参数 type 必须是字符串类型');
  }
  if (!utils.isFunction(callback)) {
    throw new Error('参数 callback 必须是函数类型');
  }

  // 为了按类查找方便和节省空间
  // 将同一类型事件放到一个数组中
  // 先绑定的事件先触发
  var fns = (this._cache[type] = this._cache[type] || []);
  if (fns.indexOf(callback) === -1) {
    fns.push(callback);
  }
  return this;
};

EventEmitter.prototype.emit = function (type, data) {
  if (!type) {
    throw new Error('参数 type 是必传参数');
  }

  if (!utils.isString(type)) {
    throw new Error('参数 type 必须是字符串类型');
  }

  var fns = this._cache[type];
  if (utils.isArray(fns)) {
    fns.forEach(function (fn) {
      fn(data);
    });
  }
  return this;
};

EventEmitter.prototype.off = function (type, callback) {
  if (!type || !callback) {
    throw new Error('参数 type, callback 是必传参数');
  }
  if (!utils.isString(type)) {
    throw new Error('参数 type 必须是字符串类型');
  }
  if (!utils.isFunction(callback)) {
    throw new Error('参数 callback 必须是函数类型');
  }

  var fns = this._cache[type];
  if (utils.isArray(fns)) {
    if (callback) {
      var index = fns.indexOf(callback);
      if (index !== -1) {
        fns.splice(index, 1);
      }
    } else {
      // 全部清空
      fns.length = 0;
    }
  }
  return this;
};
